package com.bckj.fastboot.flowable.util;

import com.bckj.fastboot.flowable.model.*;
import org.flowable.bpmn.model.*;
import org.springframework.util.StringUtils;

import java.util.Optional;

public class ProcUtils {

    public static FlowElement convert(ProcElement element) {
        FlowElement flowElement;
        if (element instanceof ProcStartEvent) {
            flowElement = new StartEvent();
        } else if (element instanceof ProcEndEvent) {
            flowElement = new EndEvent();
        } else if (element instanceof ProcUserTask) {
            flowElement = new UserTask();
        } else if (element instanceof ProcServiceTask procServiceTask) {
            var serviceTask = new ServiceTask();
            if (StringUtils.hasText(procServiceTask.getFlowableClass())) {
                serviceTask.setImplementation(procServiceTask.getFlowableClass());
                serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
            } else if (StringUtils.hasText(procServiceTask.getFlowableDelegateExpression())) {
                serviceTask.setImplementation(procServiceTask.getFlowableDelegateExpression());
                serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
            } else if (StringUtils.hasText(procServiceTask.getFlowableExpression())) {
                serviceTask.setImplementation(procServiceTask.getFlowableExpression());
                serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION);
            }
            flowElement = serviceTask;
        } else if (element instanceof ProcExclusiveGateway) {
            flowElement = new ExclusiveGateway();
        } else if (element instanceof ProcParallelGateway) {
            flowElement = new ParallelGateway();
        } else if (element instanceof ProcCallActivity procCallActivity) {
            CallActivity callActivity = new CallActivity();
            callActivity.setCalledElement(procCallActivity.getCalledElement());
            Optional.ofNullable(procCallActivity.getInParameters()).ifPresent(inParameters -> {
                for (ProcIOParameter pip : inParameters) {
                    IOParameter param = new IOParameter();
                    param.setSource(pip.getSource());
                    param.setSourceExpression(pip.getSourceExpression());
                    param.setTarget(pip.getTarget());
                    param.setTargetExpression(pip.getTargetExpression());
                    param.setTransient(pip.isTransient());
                    callActivity.addInParameter(param);
                }
            });
            Optional.ofNullable(procCallActivity.getOutParameters()).ifPresent(inParameters -> {
                for (ProcIOParameter pip : inParameters) {
                    IOParameter param = new IOParameter();
                    param.setSource(pip.getSource());
                    param.setSourceExpression(pip.getSourceExpression());
                    param.setTarget(pip.getTarget());
                    param.setTargetExpression(pip.getTargetExpression());
                    param.setTransient(pip.isTransient());
                    callActivity.addOutParameter(param);
                }
            });
            flowElement = callActivity;
        } else {
            throw new IllegalArgumentException("不支持的流程元素类型：" + element.getClass().getName());
        }
        flowElement.setId(element.getBizId());
        flowElement.setName(element.getName());
        return flowElement;
    }
}
